package com.hzhh123.channel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import org.junit.Test;
/**
 * Selector选择器
 * @author hzhh123
 * @Date 2019年2月25日 上午11:09:15
 */
public class SelectorDemo {
	/**
	 * 服务器端
	 */
	@Test
	public void test1() {
		try {
			ServerSocketChannel server= ServerSocketChannel.open();//新建NIO通道 
			//打开一个选择器
			Selector selector=Selector.open();
			server.configureBlocking(false);//设置通道为非阻塞
			ServerSocket socket=server.socket();
			socket.bind(new InetSocketAddress("127.0.0.1",1234));
			SelectionKey selectionKey = server.register(selector, SelectionKey.OP_ACCEPT);
			while (true) {
				int readyChannels=selector.select();
				if(readyChannels==0)continue;
				Set<SelectionKey> selectedKeys = selector.selectedKeys();
				Iterator<SelectionKey>it=selectedKeys.iterator();
				while(it.hasNext()) {
					SelectionKey key=it.next();
					if(key.isConnectable()){
						 //与远程服务器建立了连接
						System.out.println("与远程服务器建立了连接");
					}else if(key.isAcceptable()) {
						System.out.println("一个连接被ServerSocketChannel接受");
						// 返回为之创建此键的通道。
			            server = (ServerSocketChannel) selectionKey.channel();
			            // 接受到此通道套接字的连接。
			            // 此方法返回的套接字通道（如果有）将处于阻塞模式。
			            SocketChannel client  = server.accept();
			            // 配置为非阻塞
			            client.configureBlocking(false);
			            // 注册到selector，等待连接
			            client.register(selector, SelectionKey.OP_READ);
					}else if(key.isReadable()) {
						System.out.println("一个channel做好了读准备");
					}else if (key.isWritable()) {
						System.out.println("一个channel做好了写准备");
					}
					it.remove();
				}
				
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void test2() {
		try {
			Selector selector = Selector.open();
			SocketChannel channel = SocketChannel.open();
			channel.configureBlocking(false);
			channel.connect(new InetSocketAddress("127.0.0.1", 1234));
			SelectionKey key = channel.register(selector, SelectionKey.OP_CONNECT);
			if(key.isConnectable()) {
				SocketChannel client = (SocketChannel) key.channel();
				//完成套接字通道的连接过程
				if(client.isConnectionPending()) {
					System.out.println("客户端连接上了");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
